using System;
using System.Resources;
using System.Drawing;
using System.Collections;
using System.Reflection;
using System.ComponentModel;
using System.Text;
using System.IO;
using Microsoft.BizTalk.Message.Interop;
using Microsoft.BizTalk.Component.Interop;
using System.Xml;

namespace HIPAA_Pipelines
{

    [ComponentCategory(CategoryTypes.CATID_PipelineComponent)]
    [ComponentCategory(CategoryTypes.CATID_Any)]
    [System.Runtime.InteropServices.Guid("9d0e4103-4cce-4536-83fa-4a5040674ad6")]
    public class EDI_BAM_Correlation_Component :
        IBaseComponent,
        Microsoft.BizTalk.Component.Interop.IComponent,
        Microsoft.BizTalk.Component.Interop.IPersistPropertyBag,
        IComponentUI
    {
        static ResourceManager resManager = new ResourceManager("HIPAA_Pipelines.MessageUnenrichmentComponent", Assembly.GetExecutingAssembly());
        

        // Component information
        #region IBaseComponent
        public string Name { get { return "EDI BAM Correlation Component"; } }
        public string Version { get { return "1.0"; } }
        public string Description { get { return "This component correlates the original ISA13, GS06, ST02 Segments with the generated ones from the EDI Assembler"; } }
        public IntPtr Icon
        {
            get
            {
                return new System.IntPtr();
            }
        }
        public System.Collections.IEnumerator Validate(object projectSystem)
        {
            return null;
        }

        #endregion

        //private System.Resources.ResourceManager resourceManager =
        //    new System.Resources.ResourceManager("MessageEnrichment", Assembly.GetExecutingAssembly());

        
        #region IPersistPropertyBag Members

        public void InitNew()
        {
        }

        public void GetClassID(out Guid classID)
        {
            classID = new Guid("48BEC85A-20EE-40ad-BFD0-319B59A0DDBC");
        }

        public void Load(IPropertyBag propertyBag, int errorLog)
        {
           
        }
        public void Save(IPropertyBag propertyBag, bool clearDirty, bool saveAllProperties)
        {
           

        }

        #endregion

        #region IComponent Members
        /// <summary>
        /// This method will take a document with a structure of X12EnrichedMessage_MSGTYPE (X12_00401_270 for example)
        /// And return a simple EDI message with just the unenriched data.
        /// </summary>
        /// <param name="pContext"></param>
        /// <param name="pInMsg"></param>
        /// <returns></returns>
        public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg)
        {
            IBaseMessageContext context = pInMsg.Context;
            
            //Get the previous ISA and the New ISA

            //BUGBUG - Looks like the EDI Assembler does not reset the Context properties
            //We have an expensive operation here of reading in the EDI Stream and parsing it manually
            //Read the entire EDI Message into the body segment
            TextReader _rdr = new System.IO.StreamReader(pInMsg.BodyPart.GetOriginalDataStream());

            string EntireEDI = _rdr.ReadToEnd().ToString();
            char _elementSeparator = '~';
            string[] _splittedInput = EntireEDI.Trim('\r', '\n').Split(_elementSeparator);
            string _generatedISA = _splittedInput[0];
            string _generatedGS = _splittedInput[1];
            string _generatedTS = _splittedInput[2];

            //We can look at the context here because the EDI Assembler did not reset the properties.
            string _originalISASegment = context.Read("ISA_Segment", "http://schemas.microsoft.com/Edi/PropertySchema") as string;
            string _originalGSSegment = context.Read("GS_Segment", "http://schemas.microsoft.com/Edi/PropertySchema") as string;

            //Read the original MessageID from the context properties found in the HIPAA Pipelines CustomMessageContextSchema
            string BTSMessageID = pInMsg.MessageID.ToString();
            string BTSMessageID_Original = context.Read("OrchMessageID", "http://HIPAA_Schemas.CustomMessageContextSchema") as string;
            string BTSInterchangeID = context.Read("InterchangeID", "http://schemas.microsoft.com/BizTalk/2003/system-properties") as string;
            string BTSInterchangeID_Original = context.Read("OrchInterchangeID", "http://HIPAA_Schemas.CustomMessageContextSchema") as string;
            string OriginalST02 = context.Read("OriginalST02", "http://HIPAA_Schemas.CustomMessageContextSchema") as string;
            
            string separator;
            HeadersISA _oldISA = MessageEnrichmentLibrary.EDIHeaders.ParseX12ISAHeader(_originalISASegment,out separator);
            HeadersISA _newISA = MessageEnrichmentLibrary.EDIHeaders.ParseX12ISAHeader(_generatedISA, out separator);
            HeadersGS _oldGS = MessageEnrichmentLibrary.EDIHeaders.ParseX12GSHeader(_originalGSSegment, separator);
            HeadersGS _newGS = MessageEnrichmentLibrary.EDIHeaders.ParseX12GSHeader(_generatedGS, separator);

            string MessageType_ST01 = context.Read("ST01_MessageType", "http://HIPAA_Schemas.CustomMessageContextSchema") as string;

            string[] _stSegment = _generatedTS.Trim('\r', '\n').Split('*');

            
            GenerateTypedBamApi.DirectESApi.EDI_Correlation _correlation = new GenerateTypedBamApi.DirectESApi.EDI_Correlation(System.Guid.NewGuid().ToString());
            _correlation.BeginEDI_CorrelationActivity();
            
            _correlation.ISA13_Original_InterchangeControlNumber = _oldISA.ISA13;
            _correlation.ISA13_New_InterchangeControlNumber = _newISA.ISA13;
            _correlation.GS06_Original_GroupControlNumber = _oldGS.GS06;
            _correlation.GS06_New_GroupConrolNumber = _newGS.GS06;
            _correlation.ST02_New_TransactionSetControlNumber = _stSegment[2];
            _correlation.BTSMessageID = BTSMessageID;
            _correlation.BTSInterchangeID = BTSInterchangeID;
            _correlation.ST02_Original_TransactionSetControlNumber = OriginalST02;
            _correlation.ST01_TransactionSetIDCode = MessageType_ST01;
            _correlation.BTSMessageID_Original = BTSMessageID_Original;
            _correlation.BTSInterchangeID_Original = BTSInterchangeID_Original;
            
           
            _correlation.CommitEDI_CorrelationActivity();
            _correlation.EndEDI_CorrelationActivity();

            
            //BUGBUG - EDI Assembler should re-write context properties - remove this when R2 has been patched.
            MemoryStream _stream = new MemoryStream(Encoding.ASCII.GetBytes(EntireEDI));
            //Set the position to the beginning
            _stream.Position = 0;

            pInMsg.BodyPart.Data = _stream;

            pContext.ResourceTracker.AddResource(pInMsg.BodyPart.Data);

            //Close the original datastream
            _rdr.Close();

           
            return pInMsg;
        }
        #endregion
        #region Helper Methods

        /// <summary>
        /// Reads property value from property bag.
        /// </summary>
        /// <param name="pb">Property bag.</param>
        /// <param name="propName">Name of property.</param>
        /// <returns>Value of the property.</returns>
        private static object ReadPropertyBag(Microsoft.BizTalk.Component.Interop.IPropertyBag pb, string propName)
        {
            object val = null;
            try
            {
                pb.Read(propName, out val, 0);
            }

            catch (ArgumentException)
            {
                return val;
            }
            catch (Exception ex)
            {
                throw new ApplicationException(ex.Message);
            }
            return val;
        }

        /// <summary>
        /// Writes property values into a property bag.
        /// </summary>
        /// <param name="pb">Property bag.</param>
        /// <param name="propName">Name of property.</param>
        /// <param name="val">Value of property.</param>
        private static void WritePropertyBag(Microsoft.BizTalk.Component.Interop.IPropertyBag pb, string propName, object val)
        {
            try
            {
                pb.Write(propName, ref val);
            }
            catch (Exception ex)
            {
                throw new ApplicationException(ex.Message);
            }
        }
        #endregion
    }
}

